"""
WebSocket事件处理
处理实时通信和任务状态更新
"""

import logging
from flask import current_app
from flask_socketio import emit, join_room, leave_room, disconnect
from ..services.websocket_service import WebSocketService
from ..utils.auth_utils import get_current_user_from_token

logger = logging.getLogger(__name__)

def init_websocket_events(socketio):
    """
    初始化WebSocket事件处理器
    
    Args:
        socketio: SocketIO实例
    """
    
    @socketio.on('connect')
    def handle_connect(auth):
        """
        处理客户端连接
        
        Args:
            auth: 认证信息
        """
        try:
            # 验证用户身份
            token = auth.get('token') if auth else None
            if not token:
                logger.warning("WebSocket连接缺少认证令牌")
                disconnect()
                return False
            
            user = get_current_user_from_token(token)
            if not user:
                logger.warning("WebSocket连接认证失败")
                disconnect()
                return False
            
            user_id = user['id']
            username = user['username']
            
            # 注册连接
            ws_service = WebSocketService(current_app, socketio)
            result = ws_service.connect_user(user_id, username)
            
            if result['success']:
                logger.info(f"用户WebSocket连接成功: {username} ({user_id})")
                
                # 发送连接成功消息
                emit('connected', {
                    'success': True,
                    'message': '连接成功',
                    'user_id': user_id,
                    'username': username
                })
                
                return True
            else:
                logger.error(f"用户WebSocket连接失败: {result['error']}")
                disconnect()
                return False
                
        except Exception as e:
            logger.error(f"WebSocket连接处理失败: {str(e)}")
            disconnect()
            return False
    
    @socketio.on('disconnect')
    def handle_disconnect():
        """
        处理客户端断开连接
        """
        try:
            # 获取当前用户（如果有的话）
            # 注意：断开连接时可能无法获取用户信息
            ws_service = WebSocketService(current_app, socketio)
            ws_service.disconnect_user()
            
            logger.info("用户WebSocket断开连接")
            
        except Exception as e:
            logger.error(f"WebSocket断开连接处理失败: {str(e)}")
    
    @socketio.on('join_task_room')
    def handle_join_task_room(data):
        """
        加入任务房间以接收任务更新
        
        Args:
            data: 包含task_id的数据
        """
        try:
            task_id = data.get('task_id')
            if not task_id:
                emit('error', {'message': '缺少任务ID'})
                return
            
            # 验证任务权限
            ws_service = WebSocketService(current_app, socketio)
            result = ws_service.verify_task_permission(task_id)
            
            if not result['success']:
                emit('error', {'message': result['error']})
                return
            
            # 加入任务房间
            join_room(f"task_{task_id}")
            
            emit('joined_task_room', {
                'success': True,
                'task_id': task_id,
                'message': '已加入任务房间'
            })
            
            logger.debug(f"用户加入任务房间: {task_id}")
            
        except Exception as e:
            logger.error(f"加入任务房间失败: {str(e)}")
            emit('error', {'message': '加入任务房间失败'})
    
    @socketio.on('leave_task_room')
    def handle_leave_task_room(data):
        """
        离开任务房间
        
        Args:
            data: 包含task_id的数据
        """
        try:
            task_id = data.get('task_id')
            if not task_id:
                emit('error', {'message': '缺少任务ID'})
                return
            
            # 离开任务房间
            leave_room(f"task_{task_id}")
            
            emit('left_task_room', {
                'success': True,
                'task_id': task_id,
                'message': '已离开任务房间'
            })
            
            logger.debug(f"用户离开任务房间: {task_id}")
            
        except Exception as e:
            logger.error(f"离开任务房间失败: {str(e)}")
            emit('error', {'message': '离开任务房间失败'})
    
    @socketio.on('get_task_status')
    def handle_get_task_status(data):
        """
        获取任务状态
        
        Args:
            data: 包含task_id的数据
        """
        try:
            task_id = data.get('task_id')
            if not task_id:
                emit('error', {'message': '缺少任务ID'})
                return
            
            # 验证任务权限
            ws_service = WebSocketService(current_app, socketio)
            result = ws_service.verify_task_permission(task_id)
            
            if not result['success']:
                emit('error', {'message': result['error']})
                return
            
            # 获取任务状态（这里需要调用TaskService）
            from ..services.task_service import TaskService
            task_service = TaskService(current_app)
            status_result = task_service.get_task_status(task_id)
            
            if status_result['success']:
                emit('task_status', {
                    'task_id': task_id,
                    'status': status_result['status']
                })
            else:
                emit('error', {'message': status_result['error']})
            
        except Exception as e:
            logger.error(f"获取任务状态失败: {str(e)}")
            emit('error', {'message': '获取任务状态失败'})
    
    @socketio.on('ping')
    def handle_ping():
        """
        处理心跳检测
        """
        try:
            emit('pong', {'timestamp': int(time.time())})
        except Exception as e:
            logger.error(f"心跳检测失败: {str(e)}")
    
    @socketio.on('get_user_stats')
    def handle_get_user_stats():
        """
        获取用户统计信息
        """
        try:
            # 这里可以返回用户的任务统计、配额使用情况等
            from ..services.user_service import UserService
            from ..services.task_service import TaskService
            
            # 获取当前用户（需要从session或其他方式获取）
            # 这里简化处理，实际应该从认证信息中获取
            user_service = UserService(current_app)
            task_service = TaskService(current_app)
            
            # 发送用户统计信息
            emit('user_stats', {
                'success': True,
                'stats': {
                    'message': '统计信息获取成功'
                }
            })
            
        except Exception as e:
            logger.error(f"获取用户统计失败: {str(e)}")
            emit('error', {'message': '获取统计信息失败'})
    
    @socketio.on('subscribe_notifications')
    def handle_subscribe_notifications():
        """
        订阅用户通知
        """
        try:
            # 加入用户通知房间
            # 这里需要获取当前用户ID
            # user_id = get_current_user_id()  # 需要实现
            # join_room(f"user_{user_id}")
            
            emit('subscribed_notifications', {
                'success': True,
                'message': '已订阅通知'
            })
            
        except Exception as e:
            logger.error(f"订阅通知失败: {str(e)}")
            emit('error', {'message': '订阅通知失败'})
    
    @socketio.on('unsubscribe_notifications')
    def handle_unsubscribe_notifications():
        """
        取消订阅用户通知
        """
        try:
            # 离开用户通知房间
            # user_id = get_current_user_id()  # 需要实现
            # leave_room(f"user_{user_id}")
            
            emit('unsubscribed_notifications', {
                'success': True,
                'message': '已取消订阅通知'
            })
            
        except Exception as e:
            logger.error(f"取消订阅通知失败: {str(e)}")
            emit('error', {'message': '取消订阅通知失败'})

# 辅助函数用于发送各种类型的更新
def send_task_update(socketio, task_id, update_data):
    """
    发送任务更新到指定任务房间
    
    Args:
        socketio: SocketIO实例
        task_id: 任务ID
        update_data: 更新数据
    """
    try:
        socketio.emit('task_update', {
            'task_id': task_id,
            'update': update_data
        }, room=f"task_{task_id}")
        
        logger.debug(f"任务更新已发送: {task_id}")
        
    except Exception as e:
        logger.error(f"发送任务更新失败: {str(e)}")

def send_user_notification(socketio, user_id, notification_data):
    """
    发送用户通知
    
    Args:
        socketio: SocketIO实例
        user_id: 用户ID
        notification_data: 通知数据
    """
    try:
        socketio.emit('user_notification', {
            'notification': notification_data
        }, room=f"user_{user_id}")
        
        logger.debug(f"用户通知已发送: {user_id}")
        
    except Exception as e:
        logger.error(f"发送用户通知失败: {str(e)}")

def send_system_broadcast(socketio, message_data):
    """
    发送系统广播消息
    
    Args:
        socketio: SocketIO实例
        message_data: 消息数据
    """
    try:
        socketio.emit('system_broadcast', {
            'message': message_data
        })
        
        logger.info("系统广播已发送")
        
    except Exception as e:
        logger.error(f"发送系统广播失败: {str(e)}")

# 导入time模块
import time